<template>
  <el-button-group>
    <el-button icon="el-icon-search" size="mini" @click="handleControlDrawer"></el-button>
    <el-button icon="el-icon-refresh" size="mini" @click="handleRefreshClick"></el-button>
    <el-popover
      placement="bottom-end"
      width="150"
      trigger="click"
    >
      <el-button
        slot="reference"
        size="mini"
        icon="el-icon-s-grid"
      >
        <i
          class="fa fa-caret-down"
          aria-hidden="true"
        />
      </el-button>
      <el-checkbox
        v-model="allColumnsSelected"
        :indeterminate="allColumnsSelectedIndeterminate"
        @change="handleCheckAllChange"
      >
        全选
      </el-checkbox>
      <el-checkbox
        v-for="item in tableColumns"
        :key="item.property"
        v-model="item.visible"
        @change="handleCheckedTableColumnsChange(item)"
      >
        {{ item.label }}
      </el-checkbox>
    </el-popover>
  </el-button-group>
</template>

<script>
function sortWithRef(src, ref) {
  const result = Object.assign([], ref)
  let cursor = -1
  src.forEach(e => {
    const idx = result.indexOf(e)
    if (idx === -1) {
      cursor += 1
      result.splice(cursor, 0, e)
    } else {
      cursor = idx
    }
  })
  return result
}

export default {
  data() {
    return {
      refTable: {},
      tableColumns: [],
      allColumnsSelected: true,
      allColumnsSelectedIndeterminate: false,
      ignoreNextTableColumnsChange: false
    }
  },
  props: {
    drawerSearch: Boolean,
    hiddenColumns: {
      type: Array,
      default: () => { return [] }
    },
    ignoreColumns: {
      type: Array,
      default: () => { return [] }
    }
  },
  watch: {
    refTable() {
      this.updateTableColumns()
      this.tableColumns.forEach(column => {
        if (this.hiddenColumns.indexOf(column.property) !== -1) {
          column.visible = false
          this.updateColumnVisible(column)
        }
      })
    }
  },
  methods: {
    handleControlDrawer() {
      this.$emit('searchchange', !this.drawerSearch)
    },
    handleRefreshClick() {
      this.$emit('refreshclick')
    },
    handleTableColumn() {
      console.log(this.refTable)
    },
    findTable(vm) {
      // 通过递归方法，查询父级组件表格列表 this.$refs.table 的引用
      if (vm.$refs.table) {
        this.refTable = vm.$refs.table
        return true
      }
      if (vm.$refs.table === undefined && !!vm.$parent) {
        this.findTable(vm.$parent)
      }

      return null
    },
    updateTableColumns() {
      const table = this.refTable
      if (!table) {
        this.tableColumns = []
        return
      }
      let cols = null
      const columnFilter = e => e && e.type === 'default' && e.property && this.ignoreColumns.indexOf(e.property) === -1
      const refCols = table.columns.filter(columnFilter)
      if (this.ignoreNextTableColumnsChange) {
        this.ignoreNextTableColumnsChange = false
        return
      }
      this.ignoreNextTableColumnsChange = false
      const columns = []
      const fullTableColumns = table.$children.map(e => e.columnConfig).filter(columnFilter)
      cols = sortWithRef(fullTableColumns, refCols)
      cols.forEach(config => {
        const column = {
          property: config.property,
          label: config.label,
          visible: refCols.indexOf(config) !== -1
        }
        columns.push(column)
      })
      this.tableColumns = columns
    },
    updateColumnVisible(item) {
      const table = this.refTable
      const vm = table.$children.find(e => e.prop === item.property)
      const columnConfig = vm.columnConfig
      if (item.visible) {
        // 找出合适的插入点
        const columnIndex = this.tableColumns.indexOf(item)
        vm.owner.store.commit('insertColumn', columnConfig, columnIndex + 1, null)
      } else {
        vm.owner.store.commit('removeColumn', columnConfig, null)
      }
      this.ignoreNextTableColumnsChange = true
    },
    handleCheckAllChange(val) {
      if (val === false) {
        this.allColumnsSelected = true
        return
      }
      this.tableColumns.forEach(column => {
        if (!column.visible) {
          column.visible = true
          this.updateColumnVisible(column)
        }
      })
      this.allColumnsSelected = val
      this.allColumnsSelectedIndeterminate = false
    },
    handleCheckedTableColumnsChange(item) {
      let totalCount = 0
      let selectedCount = 0
      this.tableColumns.forEach(column => {
        ++totalCount
        selectedCount += column.visible ? 1 : 0
      })
      if (selectedCount === 0) {
        alert('请至少选择一列')
        // this.refTable.notify('请至少选择一列', CRUD.NOTIFICATION_TYPE.WARNING)
        this.$nextTick(function() {
          item.visible = true
        })
        return
      }
      this.allColumnsSelected = selectedCount === totalCount
      this.allColumnsSelectedIndeterminate = selectedCount !== totalCount && selectedCount !== 0
      this.updateColumnVisible(item)
    }
  },
  mounted() {
    this.findTable(this.$parent)
  }
}
</script>

<style>
</style>
